package org.smart4j.aop.proxy.cglibdynamicproxy.proxy;

import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;

import java.lang.reflect.Method;

/**
 * 静态代理：如果接口变了，实现类要动，代理类也要动。
 * jdk提供的DynamicProxy动态代理：接口变了这个动态代理类不用动，缺点：代理类没有任何接口的类，它就没用武之地了（然并卵）。
 * CGLib 动态代理：它虽然看起不起眼，SPRING、Hibernate这样的高端开源框架都用到它了
 * 它是一个在运行期间动态生成字节码的工具，也就是动态大理类。
 * 下面跟着我一起来用它：实现 MethodInterceptor
 * Created by lyc on 2016-04-04.
 */
public class CGLibProxy implements MethodInterceptor {
    //单列模式实例化
    private  static  CGLibProxy instance=new CGLibProxy();
    // private 构造方法，限制外界不能去new它了，换句话说，这个类被“阉割”了
    private CGLibProxy() {
    }
    public static CGLibProxy getInstance(){
        return  instance;
    }


    /**
     * 动态获取自动生成的代理对象
     * @param cls
     * @param <T>
     * @return
     */
    public <T> T getProxy(Class<T> cls){
        return (T) Enhancer.create(cls,this);
    }

    /**
     * 1、覆盖intercept方法
     * @param o              代理对象
     * @param method
     * @param objects
     * @param methodProxy    传说中的方法拦截器
     * @return
     * @throws Throwable
     */
    @Override
    public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
        before();
        Object result=methodProxy.invokeSuper(o,objects);
        after();
        return result;
    }
    /**
     * 执行前方法
     */
    private  void before(){
        System.out.println("Before");
    }

    /**
     * 执行后方法
     */
    private  void after(){
        System.out.println("After");
    }
}
